# -*- coding: utf-8 -*-
"""
Created on Tue Jan 12 11:03:06 2021

@author: 59567
"""
import numpy as np


def add_cycle_key(data):
    forecast = data['forecast']
    rolling_metrics = data['df']
    cycle_key = data['cycle_key']
    y_name = data['y_name']
    data['forecast'] = add_basic(forecast, cycle_key, y_name)
    data['df'] = add_basic(rolling_metrics, cycle_key, y_name)
    return data


def add_basic(df, cycle_key, y_name):
    rs, cs = df.shape
    for k in cycle_key:
        df[k] = '-'
    for r in range(rs):
        ind = df.index[r]
        if check_ind(ind):
            print(ind)
            names = dict(zip(cycle_key, list(ind)))
            for c in range(cs, cs + len(cycle_key)):
                k = cycle_key[c - cs]
                df.iloc[r, c] = names[k]
    return df


def check_ind(s):
    for k in ['train', 'val', 'test', 'real']:
        if k in s:
            return False
    return True


def change_targets_by_upper_and_lower(output, value):  # dict
    names = ['abs', 'sigma3', 'diff', 'trend']
    y_train_targets = value['y_train_targets']
    y_valid_targets = value['y_valid_targets']
    y_history = np.concatenate((y_train_targets, y_valid_targets)).flatten()
    y_last_period = y_valid_targets[-1][-1]
    for method in names:
        if method == 'abs':
            upper = np.max(y_history)
            lower = np.min(y_history)
        elif method == 'sigma3':
            std = np.std(y_history)
            upper = y_last_period + 3 * std
            lower = y_last_period - 3 * std
        elif method == 'diff':
            upper = y_last_period + np.max(np.diff(y_history))
            lower = y_last_period + np.min(np.diff(y_history))
        elif method == 'trend':
            yll = y_valid_targets[-2][-1]
            trend = y_last_period - yll
            future = y_last_period + trend
            upper = future + np.mean(np.diff(abs(y_history)))
            lower = future - np.mean(np.diff(abs(y_history)))
        else:
            print('-')
        output['upper_' + method] = upper
        output['lower_' + method] = lower
    # y_now = value['y_test_predictions'][0, 0]
    #
    # if y_now > upper:
    #     value['y_test_predictions'][0, 0] = upper
    #     print('predictions too big , correcting y by methods of', method)
    # if y_now < lower:
    #     value['y_test_predictions'][0, 0] = upper
    #     print('predictions too small , correcting y by methods of', method)
    return output, value
